package com.chengcang.admin.modules.sys.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chengcang.common.enums.DataTypeEnum;
import com.chengcang.admin.modules.busi.dao.BusiAddressDao;
import com.chengcang.admin.modules.busi.dao.BusiDemandDao;
import com.chengcang.admin.modules.busi.dao.BusiInvoiceHeadDao;
import com.chengcang.admin.modules.busi.dao.BusiOrderDao;
import com.chengcang.admin.modules.busi.entity.BusiAddressEntity;
import com.chengcang.admin.modules.busi.entity.BusiDemandEntity;
import com.chengcang.admin.modules.busi.entity.BusiInvoiceHeadEntity;
import com.chengcang.admin.modules.busi.entity.BusiOrderEntity;
import com.chengcang.admin.modules.security.dao.SysUserTokenDao;
import com.chengcang.admin.modules.security.entity.SysUserTokenEntity;
import com.chengcang.admin.modules.security.service.SysUserTokenService;
import com.chengcang.admin.modules.security.user.SecurityUser;
import com.chengcang.admin.modules.security.user.UserDetail;
import com.chengcang.admin.modules.sys.dao.*;
import com.chengcang.admin.modules.sys.dto.SysMinTenantDTO;
import com.chengcang.admin.modules.sys.dto.SysTenantDTO;
import com.chengcang.admin.modules.sys.entity.*;
import com.chengcang.admin.modules.sys.service.*;
import com.chengcang.common.constant.Constant;
import com.chengcang.common.constant.RedisConstant;
import com.chengcang.common.enums.UserTenantStatusEnum;
import com.chengcang.common.exception.CustomException;
import com.chengcang.common.exception.ErrorCode;
import com.chengcang.common.page.PageData;
import com.chengcang.common.redis.RedisUtils;
import com.chengcang.common.service.impl.CrudServiceImpl;
import com.chengcang.common.utils.ConvertUtils;
import com.chengcang.common.utils.DateUtils;
import com.chengcang.common.utils.PasswordUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 客户管理
 *
 * @author zhanli
 * @since 1.0.0 2023-01-05
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SysTenantServiceImpl extends CrudServiceImpl<SysTenantDao, SysTenantEntity, SysTenantDTO> implements SysTenantService {

    private final SysUserTenantDao sysUserTenantDao;
    private final SysUserDao sysUserDao;
    private final BusiInvoiceHeadDao busiInvoiceHeadDao;
    private final BusiAddressDao busiAddressDao;
    private final SysDictDataService sysDictDataService;
    private final BusiOrderDao busiOrderDao;
    private final BusiDemandDao busiDemandDao;
    private final SysRoleDao sysRoleDao;
    private final SysUserTokenDao sysUserTokenDao;
    private final SysTenantBindingsDao sysTenantBindingsDao;

    private final SysTenantMenuService sysTenantMenuService;
    private final SysRoleMenuService sysRoleMenuService;
    private final SysUserTokenService sysUserTokenService;
    private final SysTenantBindingsService sysTenantBindingsService;
    private final RedisUtils redisUtils;


    @Override
    public QueryWrapper<SysTenantEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");
        QueryWrapper<SysTenantEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);
        return wrapper;
    }

    private String getNumber() {
        String datePattern = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_MS_PATTERN);
        int random = NumberUtil.generateRandomNumber(1000, 10000, 1)[0];
        return datePattern + random;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(SysTenantDTO dto) {
        // 客户信息+工商信息，账号信息，发票抬头信息
        if (dto.getId() == null) {
            insertTenantInfo(dto);
        } else {
            updateTenantInfoById(dto);
        }

    }

    private void updateTenantInfoById(SysTenantDTO dto) {
        SysTenantEntity sysTenantEntity = ConvertUtils.sourceToTarget(dto, SysTenantEntity.class);
        updateById(sysTenantEntity);
        // 更新用户
        SysUserTenantEntity userTenantEntity = sysUserTenantDao.selectOne(new LambdaQueryWrapper<SysUserTenantEntity>()
                .eq(SysUserTenantEntity::getUserType, 1)
                .eq(SysUserTenantEntity::getTenantId, sysTenantEntity.getId()));
        if (userTenantEntity != null) {
            SysUserEntity sysUserEntity = sysUserDao.selectOne(new LambdaQueryWrapper<SysUserEntity>()
                    .eq(SysUserEntity::getId, userTenantEntity.getUserId()));
            sysUserEntity.setGender(dto.getGender());
            sysUserEntity.setRealName(dto.getRealName());
            sysUserDao.updateById(sysUserEntity);
        }

        // 更新发票抬头
        BusiInvoiceHeadEntity invoiceHead = new BusiInvoiceHeadEntity();
        invoiceHead.setDefaulted(null);
        BeanUtils.copyProperties(dto, invoiceHead);
        busiInvoiceHeadDao.update(invoiceHead, new LambdaQueryWrapper<BusiInvoiceHeadEntity>()
                .eq(BusiInvoiceHeadEntity::getTenantId, sysTenantEntity.getId()).eq(BusiInvoiceHeadEntity::getDefaulted, 0));

        // 更新默认地址
        BusiAddressEntity busiAddressEntity = new BusiAddressEntity();
        BeanUtils.copyProperties(dto, busiAddressEntity);
        busiAddressEntity.setAddressMobile(dto.getAddressMobile());
        busiAddressEntity.setDefaulted(null);
        busiAddressDao.update(busiAddressEntity, new LambdaQueryWrapper<BusiAddressEntity>()
                .eq(BusiAddressEntity::getTenantId, sysTenantEntity.getId()).eq(BusiAddressEntity::getDefaulted, 0));

        sysTenantBindingsDao.delete(new LambdaQueryWrapper<SysTenantBindingsEntity>().eq(SysTenantBindingsEntity::getTenantId, sysTenantEntity.getId()));
        // 设置binding客户数据
        if (StringUtils.isNotBlank(dto.getBindingCustomers())) {
            List<SysTenantBindingsEntity> bindingTenantId = Arrays.stream(dto.getBindingCustomers().split(","))
                    .map(o -> new SysTenantBindingsEntity(sysTenantEntity.getId(), Long.parseLong(o))).collect(Collectors.toList());
            sysTenantBindingsService.insertBatch(bindingTenantId);
        }
    }


    private void insertTenantInfo(SysTenantDTO dto) {
        SysTenantEntity sysTenantEntity = ConvertUtils.sourceToTarget(dto, SysTenantEntity.class);
        sysTenantEntity.setTenantCode(getNumber());
        insert(sysTenantEntity);

        // 设置客户管理员,如果已存在则跳过，密码默认88888888
        defaultUserInsert(dto, sysTenantEntity);

        // 存储发票信息
        BusiInvoiceHeadEntity invoiceHead = new BusiInvoiceHeadEntity();
        BeanUtils.copyProperties(dto, invoiceHead);
        invoiceHead.setTenantId(sysTenantEntity.getId());
        invoiceHead.setDefaulted(0);
        busiInvoiceHeadDao.insert(invoiceHead);

        // 设置默认地址
        BusiAddressEntity busiAddressEntity = new BusiAddressEntity();
        BeanUtils.copyProperties(dto, busiAddressEntity);
        busiAddressEntity.setAddressMobile(dto.getAddressMobile());
        busiAddressEntity.setTenantId(sysTenantEntity.getId());
        busiAddressEntity.setDefaulted(0);
        busiAddressDao.insert(busiAddressEntity);

        // 目前分配所有菜单
        assignMenu(sysTenantEntity.getId(), sysTenantEntity.getTenantType());

        // 设置binding客户数据
        if (StringUtils.isNotBlank(dto.getBindingCustomers())) {
            List<SysTenantBindingsEntity> bindingTenantId = Arrays.stream(dto.getBindingCustomers().split(","))
                    .map(o -> new SysTenantBindingsEntity(sysTenantEntity.getId(), Long.parseLong(dto.getBindingCustomers()))).collect(Collectors.toList());
            sysTenantBindingsService.insertBatch(bindingTenantId);
        }
    }

    private void defaultUserInsert(SysTenantDTO dto, SysTenantEntity sysTenantEntity) {
        Wrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUsername, dto.getMobile());
        SysUserEntity sysUserEntity = sysUserDao.selectOne(queryWrapper);
        if (sysUserEntity == null) {
            sysUserEntity = new SysUserEntity();
            BeanUtils.copyProperties(dto, sysUserEntity);
            sysUserEntity.setStatus(0);
            sysUserEntity.setUserCode(getNumber());
            sysUserEntity.setUsername(dto.getMobile());
            sysUserEntity.setPassword(PasswordUtils.encode(PasswordUtils.DEFAULT_PASSWORD));
            sysUserEntity.setDefaultUserType(1);
            sysUserEntity.setDefaultTenantId(sysTenantEntity.getId());
            sysUserDao.insert(sysUserEntity);
        }
        // 设置关联表
        SysUserTenantEntity userTenantDTO = new SysUserTenantEntity();
        userTenantDTO.setTenantId(sysTenantEntity.getId());
        userTenantDTO.setUserId(sysUserEntity.getId());
        userTenantDTO.setUserType(1);
        sysUserTenantDao.insert(userTenantDTO);
    }

    private void assignMenu(Long tenantId, Integer tenantType) {
        LambdaQueryWrapper<SysRoleEntity> lambdaQueryWrapper = new LambdaQueryWrapper<SysRoleEntity>()
                .eq(SecurityUser.getTenantId() != null, SysRoleEntity::getTenantId, SecurityUser.getTenantId()).in(SysRoleEntity::getName, "工厂", "公司", "散户");
        List<SysRoleEntity> sysRoleEntities = sysRoleDao.selectList(lambdaQueryWrapper);
        if (sysRoleEntities.size() > 0) {
            String tenantTypeName = sysDictDataService.getValue(DataTypeEnum.TENANT_TYPE, String.valueOf(tenantType));
            Map<String, List<Long>> roleMenuIdMap = sysRoleEntities.stream().collect(Collectors.toMap(SysRoleEntity::getName, o -> sysRoleMenuService.getMenuIdList(o.getId())));
            if (roleMenuIdMap.containsKey(tenantTypeName)) {
                sysTenantMenuService.assign(tenantId, roleMenuIdMap.get(tenantTypeName).toArray(new Long[]{}));
            }
        }
    }

    @Override
    public List<SysMinTenantDTO> tenantList(SysMinTenantDTO sysMinTenantDTO) {
        LambdaQueryWrapper<SysTenantEntity> queryWrapper = new LambdaQueryWrapper<SysTenantEntity>()
                .like(StringUtils.isNotBlank(sysMinTenantDTO.getName()), SysTenantEntity::getName, sysMinTenantDTO.getName())
                .eq(sysMinTenantDTO.getTenantType() != null, SysTenantEntity::getTenantType, sysMinTenantDTO.getTenantType())
                .eq(SysTenantEntity::getStatus, UserTenantStatusEnum.ENABLED.value())
                .eq(SysTenantEntity::getDeleted, 0).select(SysTenantEntity::getId, SysTenantEntity::getName, SysTenantEntity::getTenantType);
        List<SysTenantEntity> sysTenantEntities = baseDao.selectList(queryWrapper);
        return ConvertUtils.sourceToTarget(sysTenantEntities, SysMinTenantDTO.class);
    }

    @Override
    public Integer forbidTenant(Long tenantId, Integer deleted) {
        SysTenantEntity sysTenantEntity = new SysTenantEntity();
        sysTenantEntity.setId(tenantId);
        sysTenantEntity.setStatus(deleted);
        int updateCount = baseDao.updateById(sysTenantEntity);
        if (deleted == UserTenantStatusEnum.DISABLE.value()) {
            logoutByTenantId(tenantId);
        }
        return updateCount;
    }

    @Override
    public void delete(Long[] ids) {
        super.delete(ids);
        logoutByTenantId(ids);
    }

    private void logoutByTenantId(Long... ids) {
        for (Long id : ids) {
            List<SysUserTenantEntity> userTenantEntities = sysUserTenantDao.selectList(new LambdaQueryWrapper<SysUserTenantEntity>()
                    .eq(SysUserTenantEntity::getTenantId, id));
            if (CollectionUtils.isNotEmpty(userTenantEntities)) {
                userTenantEntities.stream().map(SysUserTenantEntity::getUserId).forEach(sysUserTokenService::logout);
            }

        }
    }

    @Override
    public PageData<SysTenantDTO> page(Map<String, Object> params) {
        IPage<SysTenantEntity> page = getPage(params, Constant.CREATE_DATE, false);
        List<SysTenantEntity> list = baseDao.getList(page, params);
        PageData<SysTenantDTO> pageData = getPageData(list, page.getTotal(), SysTenantDTO.class);
        // 查默认用户
        List<Long> tenantIds = pageData.getList().stream().map(SysTenantDTO::getId).collect(Collectors.toList());


        List<SysUserTenantEntity> userTenantEntities = sysUserTenantDao.selectList(new LambdaQueryWrapper<SysUserTenantEntity>()
                .eq(SysUserTenantEntity::getUserType, 1)
                .in(SysUserTenantEntity::getTenantId, tenantIds));

        // 查询补全数据
        Map<Long, SysUserTenantEntity> tenantUserMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(userTenantEntities)) {
            tenantUserMap = userTenantEntities.stream().collect(Collectors.toMap(SysUserTenantEntity::getTenantId, Function.identity()));
        }
        Map<Long, SysUserEntity> tenantUserDetailMap = new HashMap<>();
        if (!tenantUserMap.keySet().isEmpty()) {
            List<SysUserEntity> sysUserEntityList = sysUserDao.selectList(new LambdaQueryWrapper<SysUserEntity>()
                    .in(SysUserEntity::getId, tenantUserMap.values().stream().map(SysUserTenantEntity::getUserId).collect(Collectors.toList())));
            if (CollectionUtils.isNotEmpty(sysUserEntityList)) {
                tenantUserDetailMap = sysUserEntityList.stream().collect(Collectors.toMap(SysUserEntity::getId, Function.identity()));

            }
        }
        // 补全抬头
        Map<Long, BusiInvoiceHeadEntity> invoiceMap = new HashMap<>();
        List<BusiInvoiceHeadEntity> busiInvoiceHeadEntities = busiInvoiceHeadDao.selectList(new LambdaQueryWrapper<BusiInvoiceHeadEntity>()
                .eq(BusiInvoiceHeadEntity::getDefaulted, 0)
                .in(BusiInvoiceHeadEntity::getTenantId, tenantIds));
        if (CollectionUtils.isNotEmpty(busiInvoiceHeadEntities)) {
            invoiceMap = busiInvoiceHeadEntities.stream().collect(Collectors.toMap(BusiInvoiceHeadEntity::getTenantId, Function.identity()));
        }
        // 获取租户订单时间
        List<Map<String, Object>> lastOrderTimeMapList = busiOrderDao.selectMaps(new QueryWrapper<BusiOrderEntity>()
                .in("tenant_id", tenantIds)
                .groupBy("tenant_id")
                .select("tenant_id", "max(create_date) as max"));
        Map<Long, Object> lastOrderTimeMap = new HashMap<>(lastOrderTimeMapList.size());
        if (lastOrderTimeMapList.size() > 0) {
            lastOrderTimeMap = lastOrderTimeMapList.stream().collect(Collectors.toMap(o -> Long.valueOf(String.valueOf(o.get("tenant_id"))), v -> v.get("max")));
        }

        // 补全
        for (SysTenantDTO tenantDTO : pageData.getList()) {
            Object o2 = lastOrderTimeMap.get(tenantDTO.getId());
            if (o2 instanceof LocalDateTime) {
                tenantDTO.setLastOrderDate(DateUtils.parse((LocalDateTime) o2));
            }

            SysUserTenantEntity userTenantEntity = tenantUserMap.get(tenantDTO.getId());
            Map<Long, SysUserEntity> finalTenantUserDetailMap = tenantUserDetailMap;
            Optional.ofNullable(userTenantEntity).ifPresent(o -> {
                SysUserEntity sysUserEntity = finalTenantUserDetailMap.get(o.getUserId());
                tenantDTO.setUserType(o.getUserType());
                Optional.ofNullable(sysUserEntity).ifPresent(o1 -> {
                    tenantDTO.setMobile(o1.getMobile());
                    tenantDTO.setRealName(o1.getRealName());
                    tenantDTO.setUsername(o1.getUsername());
                });
            });
            // 发票
            BusiInvoiceHeadEntity invoiceHeadEntity = invoiceMap.get(tenantDTO.getId());
            Optional.ofNullable(invoiceHeadEntity).ifPresent(o1 -> {
                tenantDTO.setInvoiceType(o1.getInvoiceType());
                tenantDTO.setInvoiceTypeName(sysDictDataService.getValue(DataTypeEnum.INVOICE_TYPE, String.valueOf(o1.getInvoiceType())));
                tenantDTO.setInvoiceCode(o1.getInvoiceCode());
                tenantDTO.setInvoiceHead(o1.getInvoiceHead());
                tenantDTO.setInvoiceMobile(o1.getInvoiceMobile());
                tenantDTO.setInvoiceAddress(o1.getInvoiceAddress());
                tenantDTO.setInvoiceBankName(o1.getInvoiceBankName());
                tenantDTO.setInvoiceBankAccount(o1.getInvoiceBankAccount());
                tenantDTO.setInvoiceEmail(o1.getInvoiceEmail());
            });
            // 字典处理
            tenantDTO.setStatusName(sysDictDataService.getValue(DataTypeEnum.TENANT_STATUS, String.valueOf(tenantDTO.getStatus())));
            if (tenantDTO.getTenantType() != null) {
                tenantDTO.setTenantTypeName(sysDictDataService.getValue(DataTypeEnum.TENANT_TYPE, String.valueOf(tenantDTO.getTenantType())));
            }
        }

        return pageData;
    }

    @Override
    public SysTenantDTO getDetail(Long id) {
        SysTenantDTO tenantDTO = get(id);
        if (tenantDTO == null) {
            throw new CustomException(ErrorCode.TENANT_EXIST);
        }

        BusiOrderEntity busiOrderEntity = busiOrderDao.selectOne(new LambdaQueryWrapper<BusiOrderEntity>().eq(BusiOrderEntity::getTenantId, id)
                .orderByDesc(BusiOrderEntity::getCreateDate).last("limit 1"));
        if (busiOrderEntity != null) {
            tenantDTO.setLastOrderDate(busiOrderEntity.getCreateDate());
        }

        // 补充账号
        List<SysUserTenantEntity> userTenantEntities = sysUserTenantDao.selectList(new LambdaQueryWrapper<SysUserTenantEntity>()
                .eq(SysUserTenantEntity::getTenantId, tenantDTO.getId())
        );
        if (CollectionUtils.isNotEmpty(userTenantEntities)) {
            LambdaQueryWrapper<SysUserEntity> queryWrapper = new LambdaQueryWrapper<SysUserEntity>()
                    .eq(SysUserEntity::getDefaultUserType, 1)
                    .in(SysUserEntity::getId, userTenantEntities.stream().map(SysUserTenantEntity::getUserId).collect(Collectors.toList()));
            SysUserEntity sysUserEntity = sysUserDao.selectOne(queryWrapper);
            tenantDTO.setRealName(sysUserEntity.getRealName());
            tenantDTO.setMobile(sysUserEntity.getMobile());
            tenantDTO.setGender(sysUserEntity.getGender());
        }
        // 补充抬头
        LambdaQueryWrapper<BusiInvoiceHeadEntity> queryWrapper = new LambdaQueryWrapper<BusiInvoiceHeadEntity>()
                .eq(BusiInvoiceHeadEntity::getTenantId, id)
                .eq(BusiInvoiceHeadEntity::getDefaulted, 0);
        BusiInvoiceHeadEntity invoiceHeadEntity = busiInvoiceHeadDao.selectOne(queryWrapper);

        if (invoiceHeadEntity != null) {
            tenantDTO.setInvoiceHead(invoiceHeadEntity.getInvoiceHead());
            tenantDTO.setInvoiceCode(invoiceHeadEntity.getInvoiceCode());
            tenantDTO.setInvoiceBankName(invoiceHeadEntity.getInvoiceBankName());
            tenantDTO.setInvoiceBankAccount(invoiceHeadEntity.getInvoiceBankAccount());
            tenantDTO.setInvoiceAddress(invoiceHeadEntity.getInvoiceAddress());
            tenantDTO.setInvoiceMobile(invoiceHeadEntity.getInvoiceMobile());
            tenantDTO.setInvoiceEmail(invoiceHeadEntity.getInvoiceEmail());
            tenantDTO.setInvoiceType(invoiceHeadEntity.getInvoiceType());
            tenantDTO.setInvoiceTypeName(sysDictDataService.getValue(DataTypeEnum.INVOICE_TYPE, String.valueOf(tenantDTO.getInvoiceType())));
        }


        tenantDTO.setStatusName(sysDictDataService.getValue(DataTypeEnum.TENANT_STATUS, String.valueOf(tenantDTO.getStatus())));
        tenantDTO.setSourceName(sysDictDataService.getValue(DataTypeEnum.DATA_SOURCE, String.valueOf(tenantDTO.getSource())));
        if (tenantDTO.getTenantType() != null) {
            tenantDTO.setTenantTypeName(sysDictDataService.getValue(DataTypeEnum.TENANT_TYPE, String.valueOf(tenantDTO.getTenantType())));
        }
        // 绑定，性别
        if (StringUtils.isNotBlank(tenantDTO.getBindings())) {
            tenantDTO.setBindingNames(sysDictDataService.getJoiningValue(DataTypeEnum.TENANT_TYPE, tenantDTO.getBindings().split(",")));
        }
        Optional.ofNullable(tenantDTO.getBindingCustomers()).ifPresent(o -> {
            tenantDTO.setBindingCustomerNames(baseDao.selectBatchIds(Arrays.asList(o.split(","))).stream().map(SysTenantEntity::getName).collect(Collectors.joining(",")));
        });
        tenantDTO.setGenderName(sysDictDataService.getJoiningValue(DataTypeEnum.GENDER, String.valueOf(tenantDTO.getGender())));
        //补充收货地址
        LambdaQueryWrapper<BusiAddressEntity> eq = new LambdaQueryWrapper<BusiAddressEntity>().eq(BusiAddressEntity::getDefaulted, 0).eq(BusiAddressEntity::getTenantId, id);
        BusiAddressEntity busiAddressEntity = busiAddressDao.selectOne(eq);
        if (busiAddressEntity != null) {
            tenantDTO.setAddress(busiAddressEntity.getAddress());
            tenantDTO.setProvinceId(busiAddressEntity.getProvinceId());
            tenantDTO.setProvinceName(busiAddressEntity.getProvinceName());
            tenantDTO.setCityId(busiAddressEntity.getCityId());
            tenantDTO.setCityName(busiAddressEntity.getCityName());
            tenantDTO.setAreaId(busiAddressEntity.getAreaId());
            tenantDTO.setAreaName(busiAddressEntity.getAreaName());
            tenantDTO.setConsignee(busiAddressEntity.getConsignee());
            tenantDTO.setAddressMobile(busiAddressEntity.getAddressMobile());
            tenantDTO.setTag(busiAddressEntity.getTag());
        }
        return tenantDTO;
    }

    @Override
    public void deleteValidate(Long[] ids) {
        // 主账号不允许删除
        List<SysUserTenantEntity> sysUserTenantEntities = sysUserTenantDao.selectList(new LambdaQueryWrapper<SysUserTenantEntity>().in(ids.length > 0, SysUserTenantEntity::getTenantId, ids));
        if (CollectionUtils.isNotEmpty(sysUserTenantEntities)) {
            boolean anyMatch = sysUserTenantEntities.stream().anyMatch(o -> o.getUserType() == 1);
            if (anyMatch) {
                throw new CustomException("管理员账号不允许删除！");
            }
        }


        // 判断需求是否存在，待审核 0 履约中 1 已完成 2 已关闭 3
        boolean demandExist = busiDemandDao.exists(new LambdaQueryWrapper<BusiDemandEntity>()
                .in(BusiDemandEntity::getTenantId, ids)
                .in(BusiDemandEntity::getDemandStatus, Arrays.asList(0, 1, 2)));
        if (demandExist) {
            throw new CustomException(ErrorCode.TENANT_ORDER_DEMAND_EXIST);
        }
        // 判断订单是否存在，待付款 0 待发货 1 已发货 2 已完成 3 已关闭 4
        boolean orderExist = busiOrderDao.exists(new LambdaQueryWrapper<BusiOrderEntity>()
                .in(BusiOrderEntity::getTenantId, ids)
                .in(BusiOrderEntity::getStatus, Arrays.asList(0, 1, 2, 3)));
        if (orderExist) {
            throw new CustomException(ErrorCode.TENANT_ORDER_DEMAND_EXIST);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void switchTenant(UserDetail userDetail, Long tenantId) {
        log.info("切换租户记录，原默认租户: {}, 切换的tenantId:{}", SecurityUser.getTenantId(), tenantId);
        List<UserTenant> tenantList = userDetail.getTenantList();
        // 校验此租户是否为当前登录用户所拥有，否则不允许切换
        if (CollectionUtils.isNotEmpty(tenantList)) {
            UserTenant userTenantEntity = tenantList.stream().filter(o -> Objects.equals(tenantId, o.getTenantId()) && o.getUserType() == 1).findFirst().orElse(null);
            Optional.ofNullable(userTenantEntity).ifPresent(o -> SecurityUser.switchTenant(userTenantEntity.getTenantId(), userTenantEntity.getUserType(), userTenantEntity.getTenantType()));

            // 切换默认用户
            SysUserEntity sysUser = new SysUserEntity();
            sysUser.setId(userDetail.getId());
            sysUser.setDefaultUserType(userTenantEntity.getUserType());
            sysUser.setDefaultTenantId(userTenantEntity.getTenantId());
            sysUserDao.updateById(sysUser);
            // 切换token用户
            SysUserTokenEntity sysUserTokenEntity = new SysUserTokenEntity();
            sysUserTokenEntity.setTenantId(userTenantEntity.getTenantId());
            sysUserTokenDao.update(sysUserTokenEntity, new LambdaUpdateWrapper<SysUserTokenEntity>()
                    .eq(SysUserTokenEntity::getUserId, userTenantEntity.getUserId()));
        }
        // 切换的时候更改在线状态
        Optional.ofNullable(SecurityUser.getTenantId()).ifPresent(o -> {
            String userKey = RedisConstant.SYS_USER + SecurityUser.getUserId();
            Long expire = redisUtils.getExpire(userKey);
            Optional.ofNullable(expire).ifPresent(o1 -> redisUtils.set(userKey, tenantId, o1));
        });
    }
}
